home *** CD-ROM | disk | FTP | other *** search
- /*------------------------------------------------------------------*/
- /* */
- /* MC68000 Cross Assembler */
- /* */
- /* Copyright (c) 1985 by Brian R. Anderson */
- /* */
- /* Assembler directive processing - September 2, 1987 */
- /* */
- /* This program may be copied for personal, non-commercial use */
- /* only, provided that the above copyright notice is included */
- /* on all copies of the source code. Copying for any other use */
- /* without the consent of the author is prohibited. */
- /* */
- /*------------------------------------------------------------------*/
- /* */
- /* Originally published (in Modula-2) in */
- /* Dr. Dobb's Journal, April, May, and June 1986. */
- /* */
- /* AmigaDOS conversion copyright (c) 1987 by Charlie Gibbs. */
- /* */
- /*------------------------------------------------------------------*/
-
- #include <stdio.h>
- #include "a68kdef.h"
- #include "a68kglb.h"
-
- /* Functions */
- extern int LineParts(), GetField(), Instructions();
- extern int GetSize(), GetInstModeSize(), GetMultReg();
- extern int ReadSymTab(), GetArgs(), GetAReg(), OpenIncl();
- extern long AddrBndW(), AddrBndL(), GetValue(), CalcValue();
- extern char *malloc();
- extern FILE *fopen();
-
-
-
- int ObjDir (f) FILE *f;
- /* Generates Object Code for Assembler Directives */
- {
- register int i, j;
- int oploc, dummy;
- long newflags, templong;
- char tempop[MAXLINE];
-
- AddrAdv = 0;
-
- if (strcmp (OpCode, "ORG") == 0) { /* ORG */
- templong = GetValue (SrcOp, SrcLoc);
- if (Hunk2 < 0)
- Error (SrcLoc, RelErr); /* Can't ORG externally */
- else if (DefLine2 > LineCount)
- Error (SrcLoc, FwdRef); /* Illegal forward reference */
- else {
- AddrCnt = templong;
- CurrHunk = Hunk2;
- }
- PrntAddr = TRUE;
- return (Org);
- }
-
- if (strcmp (OpCode, "EQU") == 0) { /* EQU */
- if (Label[0] == '\0')
- Error (0, NeedLab); /* Need a label */
- ObjSrc = GetValue (SrcOp, SrcLoc);
- if (DefLine2 > LineCount)
- Error (SrcLoc, FwdRef); /* Illegal forward reference */
- Src.Hunk = Hunk2;
- PrntAddr = TRUE;
- return (Equ);
- }
-
- if (strcmp (OpCode, "DC") == 0) { /* DC */
- if ((Size == Word) || (Size == Long))
- AddrCnt = AddrBndW (AddrCnt);
- i = SrcLoc;
- while ((Line[i] != ' ') && (Line[i] != '\0')) {
- oploc = i;
- if (Line[i] == '\'') { /* String */
- i++; /* Skip over delimiter */
- while (i < strlen(Line)) {
- if (Line[i] == '\'') { /* End of string? */
- i++; /* Check next character */
- if (Line[i] != '\'')
- break; /* End of string */
- } /* Otherwise it's an apostrophe in string */
- Src.Hunk = ABSHUNK; /* Absolute value */
- ObjString[nX++] = Line[i++]; /* Current char. */
- }
- } else { /* Not a string constant */
- i = GetField (Line, i, SrcOp);
- ObjSrc = GetValue (SrcOp, oploc); /* Value */
- if ((Src.Hunk = Hunk2) != ABSHUNK) { /* Hunk no. */
- templong = AddrCnt + nX; /* Relocatable */
- PutRel (Srec, templong, Hunk2, Size);
- }
- if (Size == 4) {
- ObjString[nX++] = (ObjSrc >> 24) & 0x00FF;
- ObjString[nX++] = (ObjSrc >> 16) & 0x00FF;
- }
- if (Size >= 2)
- ObjString[nX++] = (ObjSrc >> 8) & 0x00FF;
- ObjString[nX++] = ObjSrc & 0x00FF;
- }
- if (Line[i] == ',')
- i++; /* Skip over separator */
- }
- if ((Line[i] != '\0') && (Line[i] != ' '))
- Error (i, OperErr); /* Didn't end properly */
- AddrAdv = InstSize = nX;
- PrntAddr = TRUE;
- return (DC);
- }
-
- if (strcmp (OpCode, "DS") == 0) { /* DS */
- AddrAdv = GetValue (SrcOp, SrcLoc);
- if (Size == Word) { /* Words */
- AddrCnt = AddrBndW (AddrCnt);
- AddrAdv <<= 1;
- }
- if (Size == Long) { /* Long words */
- AddrCnt = AddrBndW (AddrCnt);
- AddrAdv <<= 2;
- }
- if (Pass2 && (HunkType != HunkBSS)) { /* If this isn't */
- templong = AddrAdv; /* a BSS hunk, */
- while (templong >= 4) { /* generate zeros */
- AppendSdata (f, 0L, 4); /* to fill the area */
- templong -= 4;
- }
- if (templong > 0) {
- i = templong;
- AppendSdata (f, 0L, i);
- }
- }
- if (DestLoc != 0)
- Error (DestLoc, OperErr); /* Only one operand is allowed */
-
- PrntAddr = TRUE;
- return (DS);
- }
-
- if (strcmp (OpCode, "EVEN") == 0) { /* EVEN */
- AddrCnt = AddrBndW (AddrCnt);
- PrntAddr = TRUE;
- return (Even);
- }
-
- if (strcmp (OpCode, "END") == 0) { /* END */
- PrntAddr = TRUE;
- if (Pass2)
- if (SrcOp[0] != '\0')
- EndAddr = GetValue (SrcOp, SrcLoc);
- else
- EndAddr = 0;
- return (End);
- }
-
- if (strcmp (OpCode, "XDEF") == 0) { /* XDEF */
- if (SFormat)
- Error (OpLoc, NotSFmt); /* Not in S-format */
- i = SrcLoc;
- while ((Line[i] != ' ') && (Line[i] != '\0')) {
- oploc = i;
- i = GetField (Line, i, SrcOp); /* Get a symbol */
- if (ReadSymTab (SrcOp)) {
- if (!Pass2) {
- if ((Sym->Flags & 0x60) == 0)
- Sym->Flags |= 2; /* Set XDEF flag */
- } else {
- AddRef (LineCount);
- if (Sym->Defn == 0)
- Error (oploc, Undef); /* Never got defined */
- else if (Sym->Flags & 0x60)
- Error (oploc, AddrErr); /* Can't XDEF a register */
- }
- } else if (!Pass2) { /* Not yet defined */
- AddSymTab (SrcOp, 0L, CurrHunk, 0, 2);
- }
- if (Line[i] == ',')
- i++; /* Skip over separator */
- }
- return (Xdef);
- }
-
- if (strcmp (OpCode, "XREF") == 0) { /* XREF */
- if (SFormat)
- Error (OpLoc, NotSFmt); /* Not in S-format */
- i = SrcLoc;
- while ((Line[i] != ' ') && (Line[i] != '\0')) {
- oploc = i;
- i = GetField (Line, i, SrcOp);
- if (Pass2) {
- if (ReadSymTab (SrcOp) && (Sym->Defn != LineCount)) {
- AddRef (LineCount); /* Ignore extraneous XREF */
- }
- } else {
- if (!ReadSymTab (SrcOp)) { /* Only if not */
- templong = ~(HeapLim - Heap); /* defined */
- templong &= 0x0000FFFF;
- AddSymTab (SrcOp, 0L, templong, LineCount, 1);
- }
- }
- if (Line[i] == ',')
- i++; /* Skip over separator */
- }
- return (Xref);
- }
-
- if (strcmp (OpCode, "PAGE") == 0) { /* PAGE */
- if (Pass2)
- LnCnt = LnMax; /* Resume on a new page */
- return (Page);
- }
-
- if (strcmp (OpCode, "LIST") == 0) { /* LIST */
- ListOff = FALSE;
- return (DoList);
- }
-
- if ((strcmp(OpCode,"NOLIST")==0) || (strcmp(OpCode,"NOL")==0)) {
- ListOff = TRUE; /* NOLIST */
- return (NoList);
- }
-
- if (strcmp (OpCode, "SPC") == 0) { /* SPC */
- if (Pass2 && !ListOff && !SuppList) {
- if (SrcOp[0] != '\0')
- j = GetValue (SrcOp, SrcLoc); /* Amount to space */
- else
- j = 1; /* Default to one line */
- for (i = 0; i < j; i++) {
- if (LnCnt >= LnMax)
- break; /* Page overflow */
- fprintf (List, "\n"); /* Space one line */
- }
- }
- return (Space);
- }
-
- if (strcmp (OpCode, "TTL") == 0) { /* TTL */
- for (i = SrcLoc, j = 0; Line[i] != '\0'; i++) {
- TTLstring[j++] = Line[i]; /* Get title string */
- if (j >= MAXLINE - 1)
- break; /* The string is full */
- }
- TTLstring[j] = '\0';
- LnCnt = LnMax; /* Skip to a new page */
- return (Title);
- }
-
- if (strcmp (OpCode, "CNOP") == 0) { /* CNOP */
- i = TRUE; /* "Error-free" flag */
-
- ObjSrc = GetValue (SrcOp, SrcLoc);
- if (DefLine2 > LineCount) {
- Error (SrcLoc, FwdRef); /* Illegal forward reference */
- i = FALSE;
- }
- if (Hunk2 != ABSHUNK) {
- Error (SrcLoc, AbsReq); /* Must be absolute! */
- i = FALSE;
- }
-
- ObjDest = GetValue (DestOp, DestLoc);
- if (DefLine2 > LineCount) {
- Error (DestLoc, FwdRef); /* Illegal forward reference */
- i = FALSE;
- }
- if (Hunk2 != ABSHUNK) {
- Error (DestLoc, AbsReq); /* Must be absolute! */
- i = FALSE;
- }
-
- if ((ObjDest != 2) && (ObjDest != 4)) {
- Error (DestLoc, OperErr); /* DestOp must be 2 or 4 */
- i = FALSE;
- }
- if (((ObjSrc != 0) && (ObjSrc != 2)) || (ObjSrc >= ObjDest)) {
- Error (SrcLoc, OperErr); /* SrcOp must be 0 or 2 */
- i = FALSE;
- }
-
- if (i) { /* If no errors... */
- AddrCnt = AddrBndW (AddrCnt);
- if ((AddrCnt & 3L) != ObjSrc) { /* and not aligned */
- ObjOp = NOP;
- AddrAdv = InstSize = nO = 2; /* generate a NOP */
- PrntAddr = TRUE;
- }
- }
- return (Cnop);
- }
-
- if (strcmp (OpCode, "INCLUDE") == 0) { /* INCLUDE */
- i = SrcLoc;
- if ((Line[i]=='"') || (Line[i]=='\''))
- i++; /* Ignore quotes */
- j = 0;
- while ((Line[i] != ' ')
- && (Line[i] != '"')
- && (Line[i] != '\'')
- && (Line[i] != '\0'))
- tempop[j++] = Line[i++];
- tempop[j] = '\0';
- if (InF->UPtr == 0)
- InF->Pos = ftell(InFile); /* Position in outer file */
- if (!OpenIncl (tempop, InclList)) {
- Error (SrcLoc, NoIncl); /* Couldn't open file */
- if (InF->UPtr == 0) {
- InFile = fopen (InF->NPtr, "r");
- fseek (InFile, InF->Pos, 0);
- }
- return (Include); /* Return to outer file */
- }
- InFNum++; /* Bump nesting level */
- if (--InF < LowInF)
- LowInF = InF;
- Heap2Space (strlen (tempop) + 1); /* Check for space */
- InF->UPtr = 0; /* Not a user macro */
- InF->NPtr = NextFNS; /* New stack pointer */
- strcpy (NextFNS, tempop); /* File name */
- NextFNS += strlen (tempop) + 1; /* Next available space */
- if (NextFNS > High2)
- High2 = NextFNS; /* Set high-water mark */
- InF->NArg = -1; /* Flag as an INCLUDE */
- InF->Line = 0; /* Clear line counter */
- return (Include);
- }
-
- if (strcmp (OpCode, "SET") == 0) { /* SET */
- if (Label[0] == '\0')
- Error (0, NeedLab); /* Need a label */
- ObjSrc = GetValue (SrcOp, SrcLoc);
- if (DefLine2 > LineCount)
- Error (SrcLoc, FwdRef); /* Illegal forward reference */
- Src.Hunk = Hunk2;
- PrntAddr = TRUE;
- if (!ReadSymTab (Label)) /* Make a new entry */
- AddSymTab (Label, ObjSrc, Src.Hunk, LineCount, 4);
- else if (Sym->Flags & 4) { /* Re-SET the symbol */
- Sym->Val = ObjSrc; /* SET value */
- Sym->Hunk = Src.Hunk; /* Hunk number */
- Sym->Defn = LineCount; /* Statement number */
- }
- return (Set);
- }
-
- if (strcmp (OpCode, "MACRO") == 0) { /* MACRO */
- Dir = Macro;
- tempop[0] = ' ';
- i = 0; /* Prepend name with a */
- j = 1; /* blank and convert */
- while (Label[i]) /* it to upper case */
- tempop[j++] = toupper (Label[i++]);
- tempop[j] = '\0';
-
- if (!Pass2) { /* Pass 1 */
- if (Label[0] != '\0') { /* Need a label */
- templong = HeapLim - Heap; /* Offset to text */
- if (!ReadSymTab (tempop)) /* Save MACRO name */
- AddSymTab (tempop, 0L, templong, LineCount, 8);
- AddMacLine (Line); /* Save MACRO stmt. */
-
- while (strcmp (OpCode, "ENDM")) {
- if (LineParts (dummy))
- break; /* Premature EOF */
- AddMacLine (Line); /* Store a line */
- }
- }
- } else { /* Pass 2 */
- if (Label[0] == '\0')
- Error (0, NeedLab); /* Need a label */
- else {
- ReadSymTab (tempop);
- if (Sym->Defn != LineCount) {
- Error (0, DupMac); /* Duplicate MACRO */
- AddRef (LineCount);
- }
- }
- if (!SuppList)
- WriteListLine (List); /* Echo MACRO */
-
- while (1) {
- if (LineParts (dummy)) {
- Error (OpLoc, NoENDM); /* Premature EOF */
- break;
- } else {
- if (strcmp (OpCode, "ENDM") == 0)
- break;
- if (!SuppList)
- WriteListLine (List); /* Echo a line */
- }
- }
- }
-
- return (Macro);
- }
-
- if (strcmp (OpCode, "IFEQ") == 0) { /* IFEQ */
- ObjSrc = GetValue (SrcOp, SrcLoc);
- if (ObjSrc != 0)
- SkipNest++; /* Skip to the next ENDC */
- return (If);
- }
- if (strcmp (OpCode, "IFNE") == 0) { /* IFNE */
- ObjSrc = GetValue (SrcOp, SrcLoc);
- if (ObjSrc == 0)
- SkipNest++;
- return (If);
- }
- if (strcmp (OpCode, "IFGT") == 0) { /* IFGT */
- ObjSrc = GetValue (SrcOp, SrcLoc);
- if (ObjSrc <= 0)
- SkipNest++;
- return (If);
- }
- if (strcmp (OpCode, "IFGE") == 0) { /* IFGE */
- ObjSrc = GetValue (SrcOp, SrcLoc);
- if (ObjSrc < 0)
- SkipNest++;
- return (If);
- }
- if (strcmp (OpCode, "IFLT") == 0) { /* IFLT */
- ObjSrc = GetValue (SrcOp, SrcLoc);
- if (ObjSrc >= 0)
- SkipNest++;
- return (If);
- }
- if (strcmp (OpCode, "IFLE") == 0) { /* IFLE */
- ObjSrc = GetValue (SrcOp, SrcLoc);
- if (ObjSrc > 0)
- SkipNest++;
- return (If);
- }
- if (strcmp (OpCode, "IFC") == 0) { /* IFC */
- if (strcmp (SrcOp, DestOp) != 0)
- SkipNest++;
- return (If);
- }
- if (strcmp (OpCode, "IFNC") == 0) { /* IFNC */
- if (strcmp (SrcOp, DestOp) == 0)
- SkipNest++;
- return (If);
- }
- if (strcmp (OpCode, "IFD") == 0) { /* IFD */
- if (ReadSymTab (SrcOp))
- AddRef (LineCount);
- if (DefLine2 > LineCount)
- SkipNest++;
- return (If);
- }
- if (strcmp (OpCode, "IFND") == 0) { /* IFND */
- if (ReadSymTab (SrcOp))
- AddRef (LineCount);
- if (DefLine2 <= LineCount)
- SkipNest++;
- return (If);
- }
-
- if (strcmp (OpCode, "ENDC") == 0) /* ENDC */
- return (EndC); /* Just ignore it */
-
- if ((strcmp (OpCode, "CODE") == 0) /* CODE */
- || (strcmp (OpCode, "DATA") == 0) /* DATA */
- || (strcmp (OpCode, "BSS") == 0)) { /* BSS */
- strcpy (DestOp, OpCode); /* Convert to corresponding */
- strcpy (OpCode, "SECTION"); /* SECTION directive */
- }
- if (strcmp (OpCode, "SECTION") == 0) { /* SECTION */
- if (SFormat)
- Error (OpLoc, NotSFmt); /* Not in S-format */
- PrntAddr = TRUE;
-
- for (i = 0; DestOp[i]; i++) /* Convert section type */
- DestOp[i] = toupper (DestOp[i]); /* to upper case */
- if ((DestOp[0] == '\0') || (strcmp (DestOp, "CODE") == 0))
- newflags = HunkCode; /* Code section */
- else if (strcmp (DestOp, "DATA") == 0)
- newflags = HunkData; /* Data section */
- else if (strcmp (DestOp, "BSS") == 0)
- newflags = HunkBSS; /* BSS section */
- else {
- Error (DestLoc, OperErr); /* Invalid type */
- strcpy (DestOp, "CODE");
- newflags = HunkCode; /* Make it CODE */
- }
- newflags <<= 16; /* Shift to high-order 16 bits */
-
- tempop[0] = '\0';
- j = DestLoc + strlen (DestOp); /* Check for flags */
- if (Line[j] == ',') {
- j++;
- GetField (Line, j, tempop); /* Get specification */
- for (i = 0; tempop[i]; i++) /* Convert to */
- tempop[i] = toupper (tempop[i]); /* upper case */
- if (strcmp (tempop, "CHIP") == 0)
- newflags |= MEMF_CHIP; /* CHIP memory */
- else if (strcmp (tempop, "FAST") == 0)
- newflags |= MEMF_FAST; /* FAST memory */
- else
- Error (j, OperErr); /* Invalid */
- }
-
- if (SrcOp[0] == '\0') { /* Unnamed section */
- if ((strcmp (DestOp, "DATA") == 0)
- || (strcmp (DestOp, "BSS") == 0)) {
- Error (SrcLoc, NoSecNam); /* Must be named */
- return (Section);
- }
- }
- AddrCnt = AddrBndL (AddrCnt); /* Finish on long word */
- strcpy (tempop, " "); /* Two leading blanks */
- strcat (tempop, SrcOp); /* Section name */
- if (ReadSymTab (tempop)) { /* Scan for section name */
- if ((Sym->Hunk & 0xFFFF0000L) != (newflags & 0xFFFF0000L)) {
- Error (DestLoc, WrongTyp); /* Continuation in a */
- return (Section); /* different type */
- }
- if (HunkType != HunkNone) {
- if (Pass2) {
- AddRef (LineCount);
- DumpSdata (Srec); /* Previous hunk's data */
- if (!SFormat) {
- templong = HunkEnd; /* End of */
- putl (Srec, templong); /* previous hunk */
- }
- }
- Sect->Val = AddrCnt; /* End of old section */
- }
- Sect = Sym; /* Point to new section */
- SectLine = LineCount;
- AddrCnt = SectStart = Sym->Val; /* Continuation */
- TempAddr = StartAddr = AddrCnt;
- CurrHunk = Sym->Hunk & 0x0000FFFFL; /* Hunk no. */
- HunkType = (Sym->Hunk & 0x3FFF0000L) >> 16; /* Type */
- HunkFlags = Sym->Hunk & 0xC0000000L; /* Flags */
- if (Pass2 && !SFormat) { /* Start a new hunk */
- templong = HunkName;
- putl (f, templong);
- if (SrcOp[0])
- DumpName (f, SrcOp, 0L); /* Hunk name */
- else
- DumpName (f, " ", 0L);
- putl (f, HunkType); /* Hunk type */
- LenPos = ftell (f); /* Hunk length goes here */
- putl (f, 0L); /* For now, set it to zero */
- }
- return (Section);
- }
- if (Pass2) {
- Error (OpLoc, ManySect); /* Table overflowed in pass 1 */
- return (Section);
- }
- if (NextHunk >= ABSHUNK) /* Set up a new table entry */
- return (Section); /* Section table overflow */
-
- if (HunkType != HunkNone)
- Sect->Val = AddrCnt; /* End of old section */
-
- AddrCnt = SectStart = 0L; /* Reset location counter */
- TempAddr = StartAddr = AddrCnt;
- HunkType = (newflags & 0x3FFF0000L) >> 16; /* Type */
- HunkFlags = newflags & 0xC0000000L; /* Flags */
- SectLine = LineCount; /* Starting line number */
- CurrHunk = NextHunk++; /* Bump next hunk number */
- newflags |= CurrHunk; /* Add hunk number */
- AddSymTab (tempop, 0L, newflags, LineCount, 16); /* New entry */
- Sect = Sym; /* Pointer to new entry */
- return (Section);
- }
-
- if (strcmp (OpCode, "IDNT") == 0) { /* IDNT */
- i = SrcLoc;
- if (Line[i] == '"')
- i++; /* Ignore quotation marks */
- j = 0;
- while ((Line[i] != ' ') && (Line[i] != '"') && (Line[i] != '\0'))
- IdntName[j++] = Line[i++];
- IdntName[j] = '\0';
- return (Idnt);
- }
-
- if (strcmp (OpCode, "DCB") == 0) { /* DCB */
- if ((Size == Word) || (Size == Long))
- AddrCnt = AddrBndW (AddrCnt);
- ObjSrc = GetValue (SrcOp, SrcLoc); /* Replication factor */
- if (DefLine2 > LineCount) {
- Error (SrcLoc, FwdRef); /* Illegal forward reference */
- ObjSrc = 0;
- }
- if (Hunk2 != ABSHUNK) {
- Error (SrcLoc, AbsReq); /* Must be absolute! */
- ObjSrc = 0;
- }
- ObjDest = GetValue (DestOp, DestLoc); /* Value to replicate */
- Dest.Hunk = Hunk2;
- for (i = 0; i < ObjSrc; i++) {
- if (nX >= MAXLINE) {
- Error (SrcLoc, DCOflo); /* ObjString overflowed */
- break;
- }
- if (Dest.Hunk != ABSHUNK) {
- templong = AddrCnt + nX; /* Relocatable */
- PutRel (Srec, templong, Hunk2, Size);
- }
- if (Size == 4) {
- ObjString[nX++] = (ObjDest >> 24) & 0x00FF;
- ObjString[nX++] = (ObjDest >> 16) & 0x00FF;
- }
- if (Size >= 2)
- ObjString[nX++] = (ObjDest >> 8) & 0x00FF;
- ObjString[nX++] = ObjDest & 0x00FF;
- }
- AddrAdv = InstSize = nX;
- PrntAddr = TRUE;
- return (DCB);
- }
-
- if (strcmp (OpCode, "EQUR") == 0) { /* EQUR */
- if ((i = IsRegister (SrcOp, strlen (SrcOp))) < 0)
- Error (SrcLoc, AddrErr); /* Not a valid register */
- if (Label[0] == '\0')
- Error (0, NeedLab); /* Need a label */
- else {
- if (!ReadSymTab (Label)) /* Make a new entry */
- AddSymTab (Label, (long) i, 0L, LineCount, 0x20);
- GotEqur = TRUE; /* We have at least one EQUR */
- }
- return (Equr);
- }
-
- if (strcmp (OpCode, "REG") == 0) { /* REG */
- if (Label[0] == '\0')
- Error (0, NeedLab); /* Need a label */
- else {
- i = GetMultReg (SrcOp, FALSE, SrcLoc);
- if (!ReadSymTab (Label)) /* Make a new entry */
- AddSymTab (Label, (long) i, 0L, LineCount, 0x40);
- GotEqur = TRUE; /* We have at least one EQUR */
- }
- return (Reg);
- }
-
- return (None); /* Not a directive */
- }
-